package cn.south.campus.business.service.impl;

import cn.south.campus.business.mapper.GoodsMapper;
import cn.south.campus.business.model.bo.LoginContext;
import cn.south.campus.business.model.bo.LoginInfo;
import cn.south.campus.business.model.entity.Goods;
import cn.south.campus.business.model.enums.CampusErrorEnums;
import cn.south.campus.business.model.enums.GoodsStatusEnums;
import cn.south.campus.business.model.enums.StudentEnums;
import cn.south.campus.business.model.req.GoodsReq;
import cn.south.campus.business.model.vo.GoodsVo;
import cn.south.campus.business.service.GoodsService;
import cn.south.campus.business.service.StudentService;
import cn.south.campus.common.exceptions.BusinessException;
import cn.south.campus.common.model.enums.CommonEnums;
import cn.south.campus.common.utils.AssertUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * <p>
 * 二手商品表 服务实现类
 * </p>
 *
 * @author chow
 * @since 2024-11-13
 */
@Service
@AllArgsConstructor
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements GoodsService {

    private final GoodsMapper goodsMapper;

    private final StudentService studentService;

    @Override
    public void publishGoods(GoodsVo goodsVo) {
        Long userId = LoginContext.getContext().getId();
        int authStatus = studentService.getAuthStatus(userId);
        if (authStatus != StudentEnums.AuthStatusEnums.AUTH_SUCCESS.getCode()) {
            throw new BusinessException(CampusErrorEnums.STUDENT_AUTH_ERROR);
        }
        Goods goods = new Goods();
        goods.setCategoryId(goodsVo.getCategoryId());
        goods.setName(goodsVo.getName());
        goods.setPrice(new BigDecimal(goodsVo.getPrice()));
        goods.setUrl(goodsVo.getUrl());
        goods.setPublisher(userId);
        goods.setStock(goodsVo.getStock() == null ? 1 : goodsVo.getStock());
        goods.setRemain(goodsVo.getStock() == null ? 1 : goodsVo.getStock());
        goods.setDescription(goodsVo.getDescription());
        goods.setStatus(goodsVo.getStatus() == null ? GoodsStatusEnums.OFF_SALE.getCode() : goodsVo.getStatus());
        goodsMapper.insert(goods);
    }

    @Override
    public void changeStatus(Long goodsId, Integer status) {
        Goods goods = selectByIdAndPublisher(goodsId);
        AssertUtils.isNotNull(goods, CommonEnums.DATA_HAS_NOT_ERROR);
        if (status.equals(goods.getStatus())) {
            return;
        }
        if (status.equals(GoodsStatusEnums.ON_SALE.getCode())) {
            goods.setOnSaleTime(LocalDateTime.now());
        }
        goods.setStatus(status);
        goodsMapper.updateById(goods);
    }

    @Override
    public void deleteGoods(Long goodsId) {
        Goods goods = selectByIdAndPublisher(goodsId);
        AssertUtils.isNotNull(goods, CommonEnums.DATA_HAS_NOT_ERROR);
        goodsMapper.deleteById(goodsId);
    }

    @Override
    public GoodsVo getMeGoods(Long goodsId) {
        Goods goods = selectByIdAndPublisher(goodsId);
        return GoodsVo.convert(goods);
    }

    @Override
    public void updateGoods(GoodsVo goodsVo) {
        goodsMapper.updateById(GoodsVo.convert(goodsVo));
    }

    @Override
    public IPage<GoodsVo> pageQuery(GoodsReq req) {
        LoginInfo context = LoginContext.getContext();
        Long userId = context.getId();
        req.setUserId(userId);
        Page<Goods> goodsPage = goodsMapper.pageQuery(req.getPageDto(), req);
        return goodsPage.convert(GoodsVo::convert);
    }

    @Override
    public GoodsVo getGoods(Long goodsId) {
        Goods goods = goodsMapper.detail(goodsId);
        return GoodsVo.convert(goods);
    }

    @Override
    public IPage<GoodsVo> pageQueryMe(GoodsReq req) {
        LoginInfo context = LoginContext.getContext();
        Long userId = context.getId();
        req.setUserId(userId);
        req.setMe(true);
        Page<Goods> goodsPage = goodsMapper.pageQuery(req.getPageDto(), req);
        return goodsPage.convert(GoodsVo::convert);
    }


    private Goods selectByIdAndPublisher(Long goodsId) {
        LoginInfo context = LoginContext.getContext();
        Long userId = context.getId();
        LambdaQueryWrapper<Goods> wrapper = new LambdaQueryWrapper<Goods>()
                .eq(Goods::getId, goodsId)
                .eq(Goods::getPublisher, userId);
        return goodsMapper.selectOne(wrapper);
    }
}
